package com.cndw.kungfu.business;

import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.concurrent.Callable;

import com.cndw.asyncsync.DataSyncServer;
import com.cndw.kungfu.comm.AccessInspection;
import com.cndw.kungfu.comm.GmCommand;
import com.cndw.kungfu.comm.LocalCommand;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsSystem;
import com.cndw.kungfu.config.SystemCache;
import com.cndw.kungfu.controller.LoginController;
import com.cndw.kungfu.core.LogSyncServer;
import com.cndw.kungfu.event.IntelligenceOptimizeHandler;
import com.cndw.kungfu.event.StatisticsRobotHandler;
import com.cndw.kungfu.event.model.BusinessNoticeHandler;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.ext.NumberProcesser;
import com.cndw.kungfu.ext.PropertiesLib;
import com.cndw.kungfu.ext.TimeProcesser;
import com.cndw.kungfu.ext.WordProcesser;
import com.cndw.kungfu.model.ActivitySerialize;
import com.cndw.kungfu.model.Context;
import com.cndw.kungfu.model.DataSerialize;
import com.cndw.rpg.annotation.Controller;
import com.cndw.rpg.annotation.UnAuth;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;
import com.cndw.rpg.framework.SessionHolder;

@Controller
public class BusinessSystem {

	@UnAuth
	@GmCommand
	public ResponseMessage cache(Session session, String sign) {
		PropertiesLib.updateCache();// 部分properties配置文件重新加载
		String bakString = "ok";
		try {
			ConstantsConfig.load();
		} catch (Exception e) {
			e.printStackTrace();
		}
		BusinessNoticeHandler.restart();
		LanguageLib.load();

		return ResponseMessage.getSuccMessage(bakString);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage configReload(Session session, String sign) {
		try {
			ConstantsConfig.load();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return ResponseMessage.getSuccMessage(true);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage configSetValue(Session session, String sign, String key, String value) {
		try {
			if (!ConstantsConfig.isSysClosed() && !ConstantsConfig.isLocalHost()) {
				if (key.equals("sysCgPayRate") || key.equals("sysCgPartnerEName")) {
					LogUtil.getMain().error("err set on close " + key + " ip:" + session.getRemoteAddress());
					return ResponseMessage.getFailMessage(false);
				}
			}

			Field field = ConstantsConfig.class.getDeclaredField(key);
			ConstantsConfig.setValue(field, value);
			if (key.equals("sysLockIp")) {
				AccessInspection.reloadLockIp();
			} else if (key.equals("badWorld")) {
				WordProcesser.load();
			}

			LoginController.clearConfigMap();

			LogUtil.getMain().info("configSet " + key + " ip:" + session.getRemoteAddress());
			return ResponseMessage.getSuccMessage(Context.getBusinessServer().updateConfig(key, value));
		} catch (Exception e) {
			return ResponseMessage.getFailMessage(e.getMessage());
		}
	}

	@UnAuth
	public ResponseMessage test(Session session, String sing) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("name", ConstantsSystem.getHostName());
		map.put("ip", ConstantsSystem.getHostAddress());
		map.put("st", TimeProcesser.getDateByUnixTime(ConstantsSystem.getStartTime()));
		map.put("sysCgSvrId", ConstantsConfig.getSysCgSvrId());
		map.put("timeZone", TimeZone.getDefault().getID());
		return ResponseMessage.getSuccMessage(map);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage congfigGetValue(Session session, String sign, String key) {
		try {
			if (key.equals("debug")) {
				StringBuilder sb = new StringBuilder();
				sb.append(ConstantsSystem.getHostName()).append("\r\n");
				sb.append(ConstantsSystem.getHostAddress()).append("\r\n");
				sb.append(TimeProcesser.getDateByUnixTime(ConstantsSystem.getStartTime())).append("\r\n");
				sb.append(TimeZone.getDefault().getID()).append("\r\n");

				return ResponseMessage.getSuccMessage(sb.toString());
			}

			Field field = ConstantsConfig.class.getDeclaredField(key);
			if (field.getType() == int.class || field.getType() == Integer.class || field.getType() == String.class || field.getType() == boolean.class
					|| field.getType() == Boolean.class) {
				field.setAccessible(true);
				return ResponseMessage.getSuccMessage(field.get(null));
			} else {
				Map<String, String> map = Context.getCongfigServer().loadConfigFromDb();
				if (map.containsKey(key)) {
					return ResponseMessage.getSuccMessage(map.get(key));
				}
			}

			return ResponseMessage.getSuccMessage(false);
		} catch (Exception e) {
			return ResponseMessage.getFailMessage(e.getMessage());
		}
	}

	@UnAuth
	@GmCommand
	public ResponseMessage configGetList(Session session, String sign) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sysCgAutoNumberSuffix", ConstantsConfig.getSysCgAutoNumberSuffix());
		map.put("sysCgCrossURL", ConstantsConfig.getSysCgCrossURL());
		map.put("sysCgOpenTime", ConstantsConfig.getSysCgOpenTime());
		map.put("sysCgPartnerEName", ConstantsConfig.getSysCgPartnerEName());
		map.put("sysCgServiceId", ConstantsConfig.getSysCgServiceId());
		map.put("sysCgSvrId", ConstantsConfig.getSysCgSvrId());
		map.put("sysAccessFlag", ConstantsConfig.getSysAccessFlag());
		map.put("sysClosed", ConstantsConfig.isSysClosed());
		map.put("sysCgPayRate", ConstantsConfig.getSysCgPayRate());
		map.put("sysCgWorldId", ConstantsConfig.getSysCgWorldId());
		map.put("serverStartTime", ConstantsSystem.getStartTime());
		map.put("powerOpenTime", ConstantsSystem.getPowerOpenTime());
		map.put("powerCloseTime", ConstantsSystem.getPowerCloseTime());
		map.put("closeState", ConstantsSystem.getCloseState());
		map.put("timeZone", TimeZone.getDefault().getID());
		map.put("hostName", ConstantsSystem.getHostName());
		map.put("hostAddress", ConstantsSystem.getHostAddress());
		map.put("charset", Charset.defaultCharset().displayName());

		return ResponseMessage.getSuccMessage(map);
	}

	// @GmCommand
	@UnAuth
	public ResponseMessage info(Session session, String sign) {

		Map<String, Object> map = new LinkedHashMap<String, Object>();
		map.put("OnLine", SessionHolder.getInstance().onlineNums());
		map.put("Payer.size", Context.getCacheCenter().getPlayers().size());
		map.putAll(Context.getDataServer().info());
		map.put("DataSyncServer.size", DataSyncServer.getInstance().size());
		map.put("DataSyncServer.speed", DataSyncServer.getInstance().getMinuteSpeed());
		map.put("DataSyncServer.poolsize", DataSyncServer.getInstance().getPoolSize());
		map.put("LogSyncServer.size", LogSyncServer.getInstance().size());
		map.put("LogSyncServer.speed", LogSyncServer.getInstance().getSpeed());
		map.put("LogSyncServer.step", LogSyncServer.getInstance().getStep());
		map.put("freeMemory", NumberProcesser.format(Runtime.getRuntime().freeMemory()));
		map.put("maxMemory", NumberProcesser.format(Runtime.getRuntime().maxMemory()));
		map.put("totalMemory", NumberProcesser.format(Runtime.getRuntime().totalMemory()));

		return ResponseMessage.getSuccMessage(map);
	}

	@UnAuth
	@LocalCommand
	public ResponseMessage shutdown(Session session, String sign) {
		if (!ConstantsConfig.isLocalHost()) {
			return ResponseMessage.getSuccMessage(false);
		} else {
			Runnable command = new Runnable() {
				@Override
				public void run() {
					ConstantsConfig.setSysClosed(true);
					SystemCache.getInstance().commitSync();
					DataSerialize.getInstance().commitSync();
					ActivitySerialize.getInstance().commitSync();
					DataSyncServer.getInstance().shutDown();
					LogSyncServer.getInstance().shutDown();
					System.exit(0);
				}
			};
			Context.getTimerServer().scheduleSeconds(command, 2);

			return ResponseMessage.getSuccMessage(true);
		}
	}

	@GmCommand
	@UnAuth
	public ResponseMessage statistics(Session session, String sign, int type, int times, int sconds) {

		Callable<Integer> able = new StatisticsRobotHandler(type, times, sconds * 1000);

		Context.getTimerServer().getScheduledExecutor().submit(able);

		return ResponseMessage.getSuccMessage(true);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage syncDataSpeed(Session session, String sign, int syncSpeedMinute, int sysAysncThreads) {
		syncSpeedMinute = syncSpeedMinute > 30000 ? 30000 : syncSpeedMinute;

		DataSyncServer.getInstance().setSpeedAndStep(syncSpeedMinute, sysAysncThreads);

		return ResponseMessage.getSuccMessage(true);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage syncLogSpeed(Session session, String sign, int logSpeedMinute, int onceNums) {
		logSpeedMinute = logSpeedMinute < 10000 ? 10000 : logSpeedMinute;
		onceNums = onceNums < 100 ? 100 : onceNums;

		LogSyncServer.getInstance().setSpeedAndStep(logSpeedMinute, onceNums);

		return ResponseMessage.getSuccMessage(true);
	}

	@UnAuth
	@GmCommand
	public ResponseMessage stateOptimize(Session session, String sign, int state) {
		if (state == 1) {
			IntelligenceOptimizeHandler.setOpenOpitimize(true);
		} else {
			IntelligenceOptimizeHandler.setOpenOpitimize(false);
		}
		return ResponseMessage.getSuccMessage(true);
	}

}
